
<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <script src="avalon.js" type="text/javascript"></script>
      
        <link href="metro.css" media="all" rel="stylesheet" type="text/css" />

        <script>


            avalon.require("avalon.draggable", function() {


                function getSize(target) {
                    return target.className.match(/app_(\w+)/)[1]
                }
                function isApp(target) {
                    return target.tagName.toLowerCase() === "app"
                }
                function resetLayout(parent) {
                    var array = avalon.slice(parent.children)
                    var height = 0, column = 0, changeRow = true
                    for (var i = 0, el; el = array[i++]; ) {
                        var size = getSize(el)
                        //    avalon.log(size)
                        if (size === "small") {
                            height += 170
                            el.left = true
                            el.classList.add("noPaddingRight")
                            var next = array[i]
                            if (next && getSize(next) === "small") {
                                next.left = false
                                next.classList.remove("noPaddingRight")
                                //   avalon.log("small siblings")
                                i++
                            } else {

                                el.insertAdjacentHTML("afterEnd", "<app class='placehoder  app_small '><b>placehoder</b></app>")
                            }
                        } else if (size === "middle") {
                            height += 170
                            el.left = false
                        } else if (size === "big") {
                            height += 340
                            el.left = false
                            if (height >= 510) {
                                column++
                                avalon.log(height + "==============big")
                                if (height > 510) {
                                    el.insertAdjacentHTML("beforeBegin", "<app class='placehoder app_middle '><b>placehoder</b></app>")
                                    avalon.log("另起一行")
                                    height = 340
                                } else {
                                    avalon.log(" 归零")
                                    height = 0
                                }
                            }

                        }
                        if (height >= 510) {
                            //  avalon.log(height + "============累加")
                            height = 0
                            column++
                        }
                    }
                    if (height > 0) {
                        column++
                    }
                    //  avalon.log("当前列数为 " + column)
                    parent.style.width = (column) * 360 + "px"
                }
                var parent = document.querySelector(".columns");
                var lastTime

                function swipeDirection(x1, x2, y1, y2) {
                    return Math.abs(x1 - x2) >=
                            Math.abs(y1 - y2) ? (x1 - x2 > 0 ? 'left' : 'right') : (y1 - y2 > 0 ? 'up' : 'down')
                }

                var model = avalon.define("metro", function(vm) {
                    vm.array = ["middle", "small", "small", "small", "small", "small", "small", "big", "small", "small", "big", "big", "middle", "small", "small"]

                    vm.getColor = function() {
                        var letters = 'A523456789ABCDEF'.split('');
                        var color = '#';
                        for (var i = 0; i < 6; i++) {
                            color += letters[Math.round(Math.random() * 15)];
                        }
                        return color;
                    }
                    vm.current = ""
                    vm.handle = function(e) {
                        var el = e.target
                        if (/apphead/.test(el.className)) {
                            return el
                        }
                    }
                    vm.$map = []

                    vm.stop = avalon.noop
                    vm.start = function(e, data) {
                        model.$map = []
                        Array.prototype.forEach.call(document.querySelectorAll(".columns app"), function(node) {
                            if (node !== data.element) {
                                var $elem = avalon(node)
                                var offset = $elem.offset()
                                model.$map.push({
                                    top: offset.top,
                                    left: offset.left,
                                    right: offset.left + $elem.width(),
                                    bottom: offset.top + $elem.height(),
                                    node: node
                                })
                            }
                        })
                    }
                    vm.drag = function(e) {
                        var mouseX = e.pageX, mouseY = e.pageY
                        if (!lastTime || Date.now() - lastTime > 30) {
                            lastTime = Date.now()
                            for (var i = 0, obj; obj = model.$map[i++]; ) {
                                if (mouseX > obj.left && mouseX < obj.right && mouseY > obj.top && mouseY < obj.bottom) {
                                    var node = obj.node
                                    var old = document.querySelector(".hover")
                                    if (old != node) {
                                        old && old.classList.remove("hover")
                                        node.classList.add("hover")
                                    }
                                }
                            }
                        }

                    }
                    vm.beforeStop = function(e, data) {
                        data.dragX =  data.dragY = false//禁止在stop自动拖拽到最终位置
                        model.$map = []

                        var dir = swipeDirection(data.startPageX, data.pageX, data.startPageY, data.pageY)
                        setTimeout(function() {
                            var el = document.querySelector(".hover")
                            if (el) {
                                if (/placeholder/.test(el.className)) {
                                    el.parentNode.replaceChild(data.element, el)
                                } else if (dir == "left" || dir == "up") {
                                    el.parentNode.insertBefore(data.element, el || null)

                                } else {
                                    el.parentNode.insertBefore(data.element, el.nextElementSibling || null)
                                }
                                el.classList.remove("hover")
                            }
                            Array.prototype.forEach.call(document.querySelectorAll("app.placehoder"), function(node) {
                                node.parentNode.removeChild(node)
                            })
                            resetLayout(parent)
                        }, 300)
                    }

                })
                avalon.scan()

                setTimeout(function() {
                    resetLayout(parent)
                }, 200)
            })

        </script>
    </head>
    <body ms-controller="metro">
        <div class="columns"  ms-each-el="array">
            <app  ms-draggable="stop" data-start="start" data-drag="drag"  ms-attr-appindex="$index" data-before-stop="beforeStop" data-ghosting="true" data-handle="handle" ms-class="app_{{el}}" ms-class-="app{{$index}}">
                <div class="appbody" ms-css-background="getColor()">
                    <div class="apphead">APP {{$index}}</div>
                </div>
            </app>
        </div>
        <div style="position: fixed;bottom: 20px">磁贴标题可拖动&nbsp;<a href="">返回</a></div>
    </body>
</html>